#pragma once

class StringMatchDict
{
public:
	__declspec(noinline) 
	void LoadFile(LPCSTR szFileName)
	{
	}

	__declspec(noinline) 
    void SetKeyWord(LPCSTR lpKeyword, const DWORD dwSize)
    {
        sLetter *lpDictIndex = &m_DictRoot;
        LPCSTR lpKeyend = lpKeyword + dwSize;         
		
		while (lpKeyword < lpKeyend)
        {
            BYTE index = ((BYTE)*lpKeyword) >> 4;
            if (lpDictIndex->lpFollow[index] == NULL)
                lpDictIndex->lpFollow[index] = new sLetter;
            lpDictIndex = lpDictIndex->lpFollow[index];             
			index = ((BYTE)*lpKeyword) & 15;
            if (lpDictIndex->lpFollow[index] == NULL)
                lpDictIndex->lpFollow[index] = new sLetter;
            lpDictIndex = lpDictIndex->lpFollow[index];             
			lpKeyword++;
        }
		
		lpDictIndex->bLeafNode = true;
    } 
	
	__declspec(noinline) 
    BOOL Contain(LPCSTR lpKeyword, const DWORD dwSize)
    {
        sLetter *lpDictIndex = &m_DictRoot;
        LPCSTR lpKeyend = lpKeyword + dwSize;         
		
		while (lpKeyword < lpKeyend)
        {
            lpDictIndex = lpDictIndex->lpFollow[((BYTE)*lpKeyword) >> 4];
            if (lpDictIndex == NULL)
                break;             
			
			lpDictIndex = lpDictIndex->lpFollow[((BYTE)*lpKeyword) & 15];
            if (lpDictIndex == NULL)
                break;             
			
			if (lpDictIndex->bLeafNode)
                return TRUE;             
			
			lpKeyword++;
        }
		
		return FALSE;
    } 

private:
	struct sLetter
	{
		sLetter()
		{
			bLeafNode = false;
			memset(lpFollow, 0, sizeof(lpFollow));
		}         
		
		~sLetter()
		{
			Clear();
		}         
		
		
		void Clear()
		{
			for (int i=0; i<16; i++)
			{
				if (lpFollow[i] != NULL)
				{
					delete lpFollow[i];
					lpFollow[i] = NULL;
				}
			}
		}

		bool bLeafNode;
		sLetter *lpFollow[16];
	};     
	
	sLetter m_DictRoot;
};